var tgd = tgd || {};
tgd.Math = tgd.Math || {};

/* http://en.wikipedia.org/wiki/Polygon */

tgd.Math.Polygon = function () {
	this._points = [];  //anonymous objects {X, Y}
	this._area = null;
	this._centroid = null;

	if (typeof tgd.Math.Polygon._initialized == "undefined") {

		//for now assume that points are sorted
		tgd.Math.Polygon.prototype._calcArea = function() {
			this._area = 0;  //0,1,2 points area = 0 otherwise calc

			if (this._points.length >= 3) {
				for (var i = 0; i < this._points.length; ++i) {
					var currentPoint = this._points[i];
					var nextPoint = this._points[(i + 1) % this._points.length];
					this._area += (currentPoint.X * nextPoint.Y) - (nextPoint.X * currentPoint.Y)
				}

				this._area = Math.abs(this._area *= .5);
			}
		}

		tgd.Math.Polygon.prototype._calcCentroid = function() {
			this._centroid = { X: 0, Y: 0};

			if (this._points.length >= 3 && this._area != 0) {
				for (var i = 0; i < this._points.length; ++i) {
					var currentPoint = this._points[i];
					var nextPoint = this._points[(i + 1) % this._points.length];
					this._centroid.X += (currentPoint.X + nextPoint.X) * ((currentPoint.X * nextPoint.Y) - (nextPoint.X * currentPoint.Y));
					this._centroid.Y += (currentPoint.Y + nextPoint.Y) * ((currentPoint.X * nextPoint.Y) - (nextPoint.X * currentPoint.Y));
				}

				this._centroid.X = Math.abs(this._centroid.X /= (6 * this._area));
				this._centroid.Y = Math.abs(this._centroid.Y /= (6 * this._area));
			}
		}

		tgd.Math.Polygon.prototype.addPoint = function(x, y) {
			this._points.push({ X : x, Y : y });
			this._calcArea();
			this._calcCentroid();
			return this._points[this._points.length - 1];
		}

		tgd.Math.Polygon.prototype.getArea = function() {
			return this._area;
		}

		tgd.Math.Polygon.prototype.getCentroid = function() {
			return this._centroid;
		}

		tgd.Math.Polygon._initialized = true;
	}
}
